%{
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#ifndef YYSTYPE
#define YYSTYPE char*
#endif
char idstr[50];
char numstr[50];
int yylex();
extern int yyparse();
FILE* yyin;
void yyerror(const char* s);
%}

%token ADD SUBSTACT MULTIPLY DIVIDE OPEN_PARENTHESIS CLOSE_PARENTHESIS NUMBER
%token ID EQUAL 
%left ADD SUBSTACT
%left MULTIPLY DIVIDE
%right UMINUS


%%


lines   :       lines expr ';' { printf("%s\n", $2); }
        |       lines ';'
        |
        ;
//TODO:完善表达式的规则
expr    :       expr ADD expr   { 
                                    $$ = (char *)malloc(50*sizeof(char)); 
                                    strcpy($$,$1); 
                                    strcat($$,$3); 
                                    strcat($$,"+ ");
                                }
        |       expr SUBSTACT expr   { 
                                    $$ = (char *)malloc(50*sizeof(char)); 
                                    strcpy($$,$1); 
                                    strcat($$,$3); 
                                    strcat($$,"- ");
                                    }
        |       expr MULTIPLY expr  {
                                        $$=(char*)malloc(50*sizeof(char));
                                        strcpy($$,$1);
                                        strcat($$,$3);
                                        strcat($$,"* ");
                                    }
                            
        |       expr DIVIDE expr  {
                                        $$=(char*)malloc(50*sizeof(char));
                                        strcpy($$,$1);
                                        strcat($$,$3);
                                        strcat($$,"/ ");
                                    }
        |       OPEN_PARENTHESIS expr CLOSE_PARENTHESIS{
                                                            $$=(char*)malloc(50*sizeof(char));
                                                            strcpy($$,$2);
                                                        }
        |       SUBSTACT expr %prec UMINUS { 
                                    $$ = (char *)malloc(50*sizeof(char)); 
                                    strcpy($$,"-"); 
                                    strcat($$,$2); 
                                }
        |       NUMBER        { 
                                $$ = (char *)malloc(50*sizeof(char)); 
                                strcpy($$,$1); 
                                strcat($$," "); 
                                }
        |       ID            { 
                                $$ = (char *)malloc(50*sizeof(char)); 
                                strcpy($$,$1); 
                                strcat($$," "); 
                                }

        ;


%%

// programs section

int yylex()
{
    int t;
    while(1){
        t=getchar();
        if(t==' '||t=='\t'||t=='\n'){
            //do noting
        }else if(isdigit(t)){
            int index=0;
            while(isdigit(t)){
                numstr[index++]=t;
                t=getchar();
            }
            numstr[index]='\0';
            yylval=numstr;
            ungetc(t,stdin);
            return NUMBER;
        }else if(t=='+'){
            return ADD;
        }else if(t=='-'){
            return SUBSTACT;
        }
        else if(t=='*'){
            return MULTIPLY;
        }else if(t=='/')
        {
            return DIVIDE;
        }else if(t=='('){
            return OPEN_PARENTHESIS;
       }else if(t==')'){
            return CLOSE_PARENTHESIS;
        }else if(isalpha(t)){
            int index=0;
            while(isalpha(t)){
                idstr[index++]=t;
                t=getchar();
            }
            idstr[index]='\0';
            yylval=idstr;
            ungetc(t,stdin);
            return ID;
        }
        else{
            return t;
        }
    }
}

int main(void)
{
    yyin=stdin;
    do{
        yyparse();
    }while(!feof(yyin));
    return 0;
}
void yyerror(const char* s){
    fprintf(stderr,"Parse error: %s\n",s);
    exit(1);
}
